/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package servlet;

import BusinessLogic.Constants;
import BusinessLogic.CustomerBeanLocal;
import EntityState.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import javax.ejb.EJB;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.joda.time.DateTime;

/**
 *
 * @author James
 */
public class CustomerServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @EJB
    private CustomerBeanLocal customerBean;
    private ArrayList data = null;

    @Override
    public void init() {
        System.out.println("CustomerServlet: init()");
    }

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        RequestDispatcher dispatcher;
        ServletContext servletContext = getServletContext();

        String page = request.getPathInfo();
        page = page.substring(1);
        System.out.println("CustomerServlet: " + page);

        if (page.equals("") || page.equals("index")) {
            //nothing to do
            page = "index";
            data = login(request);
            request.setAttribute("data", data);
           
        } else if (page.equals("CustLoginStatus")) {
            data = login(request);
            request.setAttribute("data", data);
            
        } else if (page.equals("CustAccountRegistration")) {
            //nothing to do
        } else if (page.equals("CustAccountRegistrationConfirm")) {
            //nothing to do
        } else if (page.equals("CustAccountRegistrationStatus")) {
            data = registerAccount(request);
            request.setAttribute("data", data);

        } else if (page.equals("CheckAvailability")) {
            data = checkAvailability(request);
            request.setAttribute("data", data);
            response.setContentType("text/xml");

        } else if (page.equals("CustAccountActivation")) {
            data = activate(request);
            request.setAttribute("data", data);

        } else if (page.equals("OutletPage")) {
            //nothing to do

        } else if (page.equals("CustMakeReservation")) {
            data = reserve(request);
            request.setAttribute("data", data);

        } else if (page.equals("AddItem")) {
            data = addItem(request);
            request.setAttribute("data", data);

        } else if (page.equals("LoginStatus")) {
            data = login(request);
            request.setAttribute("data", data);
            
        } else if (page.equals("Login")) {
            data = login(request);
            request.setAttribute("data", data);
            
        } else if (page.equals("CustGetInfo")) {
            data = getInfo(request);
            request.setAttribute("data", data);
            
        } else if (page.equals("CustGetListOfPartners")) {
            data = getInfo(request);
            request.setAttribute("data", data);
            
        } else if (page.equals("CustGetPartnerProfile")) {
            data = getInfo(request);
            request.setAttribute("data", data);
            
        } else if (page.equals("CustGetOutletProfile")) {
            data = getInfo(request);
            request.setAttribute("data", data);
            
        } else if (page.equals("CustGetListOfReservableUnits")) {
            data = getInfo(request);
            request.setAttribute("data", data);

        } 

        if ((dispatcher = servletContext.getNamedDispatcher(page)) == null) {
            dispatcher = servletContext.getNamedDispatcher("Error");
        }
        dispatcher.forward(request, response);
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    private ArrayList addItem(HttpServletRequest request) {
        ArrayList list = new ArrayList();

        HashMap compulsory = Utility.getCompulsoryParameters(request, "itemID", "quantity");
        if (compulsory.isEmpty()) {
            list.add(Constants.STATUS_INVALID_INPUT);
        } else {
            String itemID = (String) compulsory.get("itemID");
            String quantity = (String) compulsory.get("quantity");
            list = customerBean.getInfo(Constants.GET_SIMPLE_ITEM_INFO, Long.parseLong(itemID));
            int result = ((Integer) list.get(0)).intValue();
            if (result == Constants.STATUS_SUCCESSFUL) {
                Cart cart = getCart(request);
                ItemState item = (ItemState) list.get(1);
                cart.addItem(item, Integer.parseInt(quantity));
            }
        }

        return list;
    }

    private ArrayList getInfo(HttpServletRequest request) {
        ArrayList list = new ArrayList();

        CustomerState us;
        if ((us = isSessionExpired(request)) == null) {
            list.add(Constants.STATUS_SESSION_EXPIRED);
        } else {
            // Get necessary information
            HashMap compulsory = Utility.getCompulsoryParameters(request, "action", "id");
            if (compulsory.isEmpty()) list.add(Constants.STATUS_INVALID_INPUT);
            else {
                int action = Integer.parseInt((String) compulsory.get("action"));
                long    id = Long.parseLong((String) compulsory.get("id"));
                System.out.println(action + " " + id);
                list = customerBean.getInfo(action, id);
                System.out.println((Integer) list.get(0));
            }
            
        }
        return list;
    }

    private ArrayList reserve(HttpServletRequest request) {
        ArrayList list = new ArrayList();

        CustomerState us;
        if ((us = isSessionExpired(request)) == null) {
            list.add(Constants.STATUS_SESSION_EXPIRED);
        } else {
            // Get necessary information
            HashMap compulsory = Utility.getCompulsoryParameters(request, "reservableUnitID", "numOfPeople", "startTime", "endTime");
            HashMap optional = Utility.getOptionalParameters(request, "name", "countryCode", "phone");
            String[] voucherIDs = request.getParameterValues("voucherID");
            if (compulsory.isEmpty()) list.add(Constants.STATUS_INVALID_INPUT);
            else {
                String reservableUnitID, numOfPeople, startTime, endTime, name, countryCode, phone;
                reservableUnitID = (String) compulsory.get("reservableUnitID");
                numOfPeople      = (String) compulsory.get("numOfPeople");
                startTime        = (String) compulsory.get("startTime");
                endTime          = (String) compulsory.get("endTime");
                name             = (String) optional.get("name");
                countryCode      = (String) optional.get("countryCode");
                phone            = (String) optional.get("phone");
                // Generate an array of voucherID
                long[] listOfVouchers = null;
                if (voucherIDs != null) {
                    listOfVouchers = new long[voucherIDs.length];
                    for (int i = 0; i < voucherIDs.length; i++) {
                        listOfVouchers[i] = Long.parseLong(voucherIDs[i]);
                    }
                }
                
                // Request the bean to reserve the slot
                if ((name.equals("") && countryCode.equals("") && phone.equals("")) || (!name.equals("") && !countryCode.equals("") && !phone.equals(""))) {
                    list = customerBean.reserve(us.getUsername(), name, countryCode, phone, Integer.parseInt(numOfPeople), Long.parseLong(startTime), Long.parseLong(endTime), Long.parseLong(reservableUnitID), listOfVouchers);
                    // If the reservation is successful, put it in the cart
                    int result = ((Integer) list.get(0)).intValue();
                    if (result == Constants.STATUS_SUCCESSFUL) {
                        Cart cart = getCart(request);
                        cart.addReservation((ReservationState) list.get(1));
                    }
                } else {
                    System.out.println("hehe");
                    list.add(Constants.STATUS_INVALID_INPUT);
                }
            }
        }

        return list;
    }

    private ArrayList checkAvailability(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        String username = request.getParameter("target");
        list.add(customerBean.checkAvailability(username));
        return list;
    }

    private ArrayList registerAccount(HttpServletRequest request) {
        ArrayList list = new ArrayList();

        //Calculate birthDay
        String day = request.getParameter("day");
        String month = request.getParameter("month");
        String year = request.getParameter("year");
        DateTime birthday = new DateTime(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day), 0, 0, 0, 0);
        //Get other information
        String IC = request.getParameter("NRIC");
        String firstName = request.getParameter("firstName");
        String lastName = request.getParameter("lastName");
        String gender = request.getParameter("sex");
        String countryCode = request.getParameter("countryCode");
        String phone = request.getParameter("phone");
        String email = request.getParameter("email1");
        String country = request.getParameter("country");
        String city = request.getParameter("city");
        String username = request.getParameter("chosenUsername");
        String password = request.getParameter("password1");

        //Create the entry for the user in the database
        list.add(customerBean.registerAccount(username, password, IC, firstName, lastName, gender, countryCode, phone, email, country, city, birthday.getMillis()));
        return list;
    }

    private ArrayList activate(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        String id = request.getParameter("id");
        list.add(customerBean.activateUser(id));
        return list;
    }

    private ArrayList login(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        CustomerState us;

        //Check if user has logined recently
        if ((us = isSessionExpired(request)) != null) {
            //Show him the user control panel 
            list.add(Constants.STATUS_SUCCESSFUL);
            list.add(us.getUsername());
        } else {
            //If new user, try to get the Username and Password
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            String timezone = request.getParameter("timezone");
            System.out.println("username: " + username);
            System.out.println("password: " + password);
            System.out.println("Timezone: " + timezone);

            //If no Username was submitted, this is a new user
            if (username == null) {
                list.add(Constants.STATUS_NEW_SESSION);
            } else {
                //If a Username was submitted, look for an entry in the database
                us = customerBean.login(username, password, timezone);
                if (us == null) {
                    list.add(Constants.STATUS_WRONG_PASSWORD); //Wrong Username or Password
                } else if (us.isActivated() && us.isActive()) { //If this user exitst, check if he activated his account
                    list.add(Constants.STATUS_SUCCESSFUL);
                    HttpSession clientSession = request.getSession();
                    clientSession.setMaxInactiveInterval(1800);
                    clientSession.setAttribute("user", us);
                    // Add a new cart to this session
                    Cart cart = new Cart();
                    clientSession.setAttribute("cart", cart);
                    clientSession.setMaxInactiveInterval(86400);
                } else {
                    if (!us.isActivated()) {
                        list.add(Constants.STATUS_USER_INACTIVATED);
                    } else if (!us.isActive()) {
                        list.add(Constants.STATUS_ACCOUNT_BANNED);
                    }
                    list.add(username);
                }
            }
        }
        return list;
    }
    
    //CUBE FUNCTIONS
    /*private ArrayList buyVoucher(HttpServletRequest request) {
        ArrayList list = new ArrayList();
        HashMap compulsory = Utility.getCompulsoryParameters(request, "voucherId", "quantity");
        if (compulsory.isEmpty()) {
            list.add(Constants.STATUS_INVALID_INPUT);
        } else {
            String voucherID = (String) compulsory.get("voucherId");
            String quantity = (String) compulsory.get("quantity");
            list = customerBean.getInfo(Constants.GET_SIMPLE_ITEM_INFO, Long.parseLong(voucherID));
            int result = ((Integer) list.get(0)).intValue();
            if (result == Constants.STATUS_SUCCESSFUL) {
                Cart cart = getCart(request);
                VoucherState voucher = (VoucherState) list.get(1);
                cart.addVoucher(voucher, Integer.parseInt(quantity));
            }
        }

        return list;
    }*/
    
    // Utility functions
    private Cart getCart(HttpServletRequest request) {
        HttpSession clientSession = request.getSession();
        Cart cart = (Cart) clientSession.getAttribute("cart");
        // Create a new cart if the customer doesn't have one
        if (cart == null) {
            cart = new Cart();
            clientSession.setAttribute("cart", cart);
        }
        return cart;
    }

    private CustomerState isSessionExpired(HttpServletRequest request) {
        HttpSession clientSession = request.getSession(false);
        if (clientSession != null) {
            CustomerState us = (CustomerState) clientSession.getAttribute("user");
            if (us != null) {
                return us;
            } else {
                return null;
            }
        } else {
            return null;
        }
    }
}
